package com.lzy.aspectj;

import com.lzy.annotation.NoRepeatSubmit;
import com.lzy.common.R;
import com.lzy.security.LoginUser;
import com.lzy.utils.RedisCache;
import com.lzy.utils.ServletUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.concurrent.TimeUnit;

/**
 * 防止重复提交
 *
 * @author lyw
 * @Date 2023/2/13-下午2:31
 */

@Aspect
@Component
public class NoRepeatSubmitAspect {

  private Log logger = LogFactory.getLog(getClass());

  @Autowired
  private RedissonClient redisson;

  @Around("execution(* com.lzy..*Controller.*(..)) && @annotation(nrs)")
  public Object doAround(ProceedingJoinPoint pjp, NoRepeatSubmit nrs) throws Throwable {

    HttpServletRequest request = ServletUtils.getRequest();
    LoginUser loginUser = (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
    Long userid = loginUser.getUser().getUserId();
    String key = userid + "-" + request.getServletPath();
    Object o = null;
    // 获取 RLock 对象
    RLock lock = redisson.getLock(key);
    try {
      boolean isSuccess = lock.tryLock(30, 10, TimeUnit.SECONDS);
      if (isSuccess) {
        // 业务逻辑
        o = pjp.proceed();
      } else {
        return R.error("验证重复提交时出现未知异常!");
      }
      return o;
    } finally {
      lock.unlock();
    }
  }
}